package com.zondy.mapgis.android.base;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;

import com.zondy.mapgis.android.activity.MapActivity;
import com.zondy.mapgis.android.map.dao.IBaseActivity;
import com.zondy.mapgis.android.map.dao.ICallBack;
import com.zondy.mapgis.android.map.dao.ICallBackGoBack;
import com.zondy.mapgis.android.map.dao.IGoBack;

/**
 * 继承{@link Activity}和{@link IBaseActivity}。<br>
 * 默认设置了 {@link Activity}的一些基本参数。 重写了返回键事件，按下返回键时，如果 {@link #goback()} 方法返回
 * <code>true</code> ，则处理完毕，否则，使用系统默认的操作。<br>
 * 为使程序整体表现一致，所有Activity均应继承该类。
 * 
 * @author fjl
 */
public  class BaseActivity extends FragmentActivity implements IBaseActivity,IGoBack
{

	/** 日志输出标志 **/
	protected final String TAG = this.getClass().getSimpleName();

	/**
	 * 原生Activity不方便在Activity之间传递复杂参数，这里直接用静态字段来储存复杂对象键值对。<br>
	 * 为保证参数能够正确传递，这里使用的是硬引用，为避免产生大量不必要的额外空间占用，<br>
	 * 强烈建议简单对象不要使用该字段储存，而是使用原生支持的 Bundle yangsheng 2015.2.8
	 */
	private static final Map<String, Object> arguments = new HashMap<String, Object>();

	/**
	 * 每个大功能的退出功能都会不一样，在{@link MapActivity}中全部写的话比较麻烦，每增加一个大的功能都要在
	 * {@link MapActivity}在些一个相应的退出功能，这样的话不可取。因此在基类中定义一个集合，每个大功能中add一个
	 * {@link Fragment}就会在堆栈{@link goBackListenerLst}中添加一条记录，当点击返回键时，就依次隐藏掉
	 * {@link Fragment}并移除对 应的记录，最后根据{@link ICallBackGoBack}.{@link #onCall()}
	 * 的返回值（int）来做相应的操作。
	 */
	public LinkedList<ICallBackGoBack> goBackListenerLst = new LinkedList<ICallBackGoBack>();

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		//隐藏标题栏(即全屏)
//		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
		//常亮
//		getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

	}

	/**
	 * {@link Activity#findViewById(int)}
	 * 
	 * @param viewId
	 * @return
	 */
	public View find(int viewId)
	{
		return findViewById(viewId);
	}

	/**
	 * 取Activity中的Fragment
	 * 
	 * @param strTag
	 * @return
	 */
	public Fragment getFragment(String strTag)
	{
		FragmentManager fm = getSupportFragmentManager();
		Fragment frag = fm.findFragmentByTag(strTag);

		return frag;
	}

	/**
	 * 隐藏Fragment
	 * 
	 * @param strTag
	 * @param callback
	 */
	public boolean hideFragment(String strTag, ICallBack callback)
	{

		FragmentManager fm = getSupportFragmentManager();
		Fragment frag = fm.findFragmentByTag(strTag);
		if (frag == null)
		{
			System.out.println("BaseActivity.showFragment, 隐藏Fragment失败，" + strTag + "frag == null");
			return false;
		}
		if (frag.isHidden())
		{
			System.out.println("BaseActivity.showFragment, Fragment已经是隐藏状态，" + strTag + "frag.isHidden() == true");
			return false;
		}
		fm.beginTransaction().hide(frag).commitAllowingStateLoss();

		if (callback != null)
		{
			callback.onCall("");
		}
		return true;
	}

	/**
	 * 显示Fragment
	 * 
	 * @param strTag
	 * @param callback
	 */
	public void showFragment(String strTag, ICallBack callback)
	{

		FragmentManager fm = getSupportFragmentManager();
		Fragment frag = fm.findFragmentByTag(strTag);
		if (frag == null)
		{
			System.out.println("BaseActivity.showFragment, 显示Fragment失败，" + strTag + "frag == null");
			return;
		}
		// if( frag.isVisible()){
		if (!frag.isHidden())
		{
			System.out.println("BaseActivity.showFragment, Fragment已经是显示状态，" + strTag + "frag.isHidden() == false");
			return;
		}
		fm.beginTransaction().show(frag).commitAllowingStateLoss();

		if (callback != null)
		{
			callback.onCall("");
		}
	}

	/**
	 * 添加Fragment
	 * 
	 * @param parentResId
	 * @param frag
	 * @param strTag
	 * @param callback
	 */
	public void addFragment(int parentResId, BaseFragment frag, String strTag, ICallBack callback)
	{

		FragmentTransaction fragTransact = getSupportFragmentManager().beginTransaction();
		// 可能已存在同名的frag
		frag.setParentViewID(parentResId);
		fragTransact.add(parentResId, frag, strTag);
		fragTransact.addToBackStack(null);
		fragTransact.commitAllowingStateLoss();

		if (callback != null)
		{
			callback.onCall(strTag);
		}
	}

	/**
	 * 移除Fragment
	 * 
	 * @param strTag
	 * @param callBack
	 */
	public boolean removeFragment(String strTag, ICallBack callBack)
	{
		FragmentManager fragManag = getSupportFragmentManager();
		Fragment frag = fragManag.findFragmentByTag(strTag);
		if (frag == null)
		{
			return false;
		}
		FragmentTransaction fragTransact = fragManag.beginTransaction();
		fragTransact.remove(frag);
		fragTransact.commitAllowingStateLoss();
		if (callBack != null)
		{
			callBack.onCall(strTag);
		}
		return true;

	}
	/**
	 * Fragment回滚（最上面的一个Fragmen出堆栈）
	 * 
	 */
	public void popBackStack()
	{
		FragmentManager fragManag = getSupportFragmentManager();
		fragManag.popBackStack();
	}

	/**
	 * 重写了返回键事件，按下返回键时，如果 {@link #goback()} 方法返回 <code>true</code>
	 * ，则处理完毕，否则，继续执行系统默认的操作。<br>
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{

		if (keyCode == KeyEvent.KEYCODE_BACK)
		{
			if (goBackListenerLst.size() > 0)
			{
				ICallBackGoBack callbackgoback = goBackListenerLst.getFirst();
				int returnCallBack = callbackgoback.onCall("");
				if (returnCallBack == 1)
				{
					goBackListenerLst.removeFirst();
					return true;
				}
				else if (returnCallBack == -1)
				{
					goBackListenerLst.removeFirst();
					return onKeyDown(keyCode, event);
				}
				else
				{
					return false;
				}
			}
			else
			{
				boolean handled = goback();

				return handled;
			}
		}
		else
		{
			return super.onKeyDown(keyCode, event);
		}
	}

	/**
	 * Activity间传递参数用。添加参数，为避免覆盖，使用该方法时应十分注意参数 strName 的唯一性
	 * 
	 * @param strName
	 * @param objValue
	 */
	public static void putArgument(String strName, Object objValue)
	{
		arguments.put(strName, objValue);
	}

	/**
	 * Activity间传递参数用。取参数，一旦成功取出参数对应的对象，该键值对将从参数Map中移除
	 * 
	 * @param strName
	 * @return
	 */
	public static Object getArgument(String strName)
	{
		Object obj = arguments.get(strName);
		if (obj != null)
		{
			arguments.remove(strName);
		}
		return obj;
	}

	/**
	 * 返回操作应集中在此处理，需要关闭当前 {@link BaseActivity} 时，可以选择直接在这里关闭并返回true，
	 * 也可以选择这里返回false，交由上一级处理（比如在 {@link #onKeyDown(int, KeyEvent)} 的 返回按钮
	 * 事件中，如果这里返回 false，则上一级处理时还是会关闭当前 {@link BaseActivity} ）。
	 */
	@Override
	public boolean goback()
	{
		this.finish();
		return true;
	}

	/**
	 * 默认使用切换动画 android.R.anim.slide_in_left, android.R.anim.slide_out_right
	 */
	@Override
	public void startActivity(Intent intent)
	{
		super.startActivity(intent);
		overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
	}

	/**
	 * 使用指定的切换动画
	 * 
	 * @param intent
	 * @param animIn
	 * @param animOut
	 */
	public void startActivity(Intent intent, int animIn, int animOut)
	{
		super.startActivity(intent);
		if (animIn < 0)
		{
			animIn = android.R.anim.slide_in_left;
		}
		if (animOut < 0)
		{
			animOut = android.R.anim.slide_out_right;
		}
		overridePendingTransition(animIn, animOut);
	}

	@Override
	public void finish()
	{
		super.finish();
		goBackListenerLst.clear();
		overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
	}

	@Override
	public void finishActivity()
	{
		finish();
	}

	/**
	 * 在所有点击弹出Fragment的时候都要调用此方法，采用堆栈的方式来储存ICallBack
	 * 当点击返回键时（调用goback()），通过堆栈的特点（先进后出）来依次隐藏或移除掉相应的Fragment
	 * callback的返回值应重视,回调执行成功返回1,回调失效返回-1,回调被取消返回0
	 * 
	 * @param callback
	 */
	public void addGoBackListener(ICallBackGoBack callback)
	{
		if (callback == null)
		{
			return;
		}
		goBackListenerLst.addFirst(callback);
	}

	/**
	 * 取返回键的堆栈回调事件，此方法主要用于插件化的返回功能
	 * 
	 * @return
	 */
	public LinkedList<ICallBackGoBack> getGoBackListener()
	{
		return goBackListenerLst;
	}

	@Override
	public void resume()
	{
		
	}

	@Override
	public void destroy()
	{
		
	}

}
